//
//  KKBLEConnect.m
//
//  Created by zorro on 2017/11/13.
//  Copyright © 2017年 zorro. All rights reserved.
//

#import "KKBLEConnect.h"
#import "KKBLEService.h"
#import "FileModelEntity.h"
#import "DownloadEntity.h"
#import "UpdateInfoView.h"

@interface KKBLEConnect () <CBCentralManagerDelegate>
{
    NSMutableArray *otaArray;
    NSString *otaName;
}
@property (nonatomic, strong) CBCentralManager *centralManager;
@property (nonatomic, strong) CBPeripheral     *discoverPeripheral;
@property (nonatomic, strong) NSTimer          *scanTimer;
@property (nonatomic, strong) KKBLEModel       *updateModel;
@property (nonatomic, strong) UpdateInfoView   *updateInfoView;
@property (nonatomic, assign) BOOL             getOtaDic;


@end

@implementation KKBLEConnect
DEF_SINGLETON(KKBLEConnect)

- (instancetype)init {
    self = [super init];
    if (self) {
        _devicesArray                   = [[NSMutableArray alloc] initWithCapacity:0];
        _centralManager                 = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
        KK_BLEService.updateModelStatus = ^(KKBLEModel *model, KKBLEUpdateType type)
        {
            [self updateModel:model type:type];
        };
        if (![KK_BLELastDevice getObjectValue]) {
            [KK_BLELastDevice setObjectValue:@""];
        }
        if (![KK_BLELastDeviceMac getObjectValue]) {
            [KK_BLELastDeviceMac setObjectValue:@""];
        }
        [self startTimerScan];
        otaArray = [NSMutableArray array];
        [otaArray addObject:[@"XW_OTA" lowercaseString]];
        [otaArray addObject:[@"DfuTarg" lowercaseString]];
        [otaArray addObject:[@"B2_OTA" lowercaseString]];
        [otaArray addObject:[@"PPlusOTA" lowercaseString]];
    }
    return self;
}

- (void)bleCenterService:(BOOL)state
{
//    if (state == NO) {
//        [_centralManager stopScan];
//        _centralManager.delegate = nil;
//        _centralManager = nil;
//    }
//    else
//    {
//        if (_centralManager) {
//            [_centralManager stopScan];
//            _centralManager.delegate = nil;
//            _centralManager = nil;
//        }
//        _centralManager                 = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
//    }
}

// 更新各种蓝牙的情况.
- (void)updateModel:(KKBLEModel *)model type:(KKBLEUpdateType)type {
    if (type == KKBLEUpdateDisConnect || type == KKBLEUpdatePowerOff || type == KKBLEUpdatePowerOn) {
        [KK_BLESend resetSendCMD];
    }
    if (_updateModelStatus) {
        _updateModelStatus(model, type);
    }
}

- (void)startTimerScan {
    if (!_scanTimer) {
        _scanTimer = [NSTimer scheduledTimerWithTimeInterval:10.0
                                                      target:self
                                                    selector:@selector(timerScanWithoutBreakConnect)
                                                    userInfo:nil
                                                     repeats:YES];
        [[NSRunLoop mainRunLoop]addTimer:_scanTimer forMode:NSRunLoopCommonModes];
    }
}

- (KKBLEModel *)model {
    if (!_model) {
        NSString *uuid = [KK_BLELastDevice getObjectValue];
        NSString *mac  = [KK_BLELastDeviceMac getObjectValue];
        if (!uuid) {
            [KK_BLELastDevice setObjectValue:@""];
        }
        if (!mac) {
            [KK_BLELastDeviceMac setObjectValue:@""];
        }
        _model = [KKBLEModel getModelFromDBWtihUUID:[KK_BLELastDevice getObjectValue]];
        LogWrite(@"上次连接设备UUID", uuid, nil);
    }
    return _model;
}

- (BOOL)isConnected {
    return KK_BLEService.isFoundChar && _model.isConnected;
}

- (BOOL)isBoindDevice {
    NSString *uuid = [KK_BLELastDevice getObjectValue];
    NSString *mac  = [KK_BLELastDeviceMac getObjectValue];
    BOOL     boind = NO;
    
    if (uuid.length > 0) {
        boind = YES;
    }
    if (mac.length > 0) {
        boind = YES;
    }
    return boind;
}

- (void)timerScanWithoutBreakConnect {
    if (_discoverPeripheral.state == CBPeripheralStateConnected) {
    } else {
        if (!_isUpdateing) {
        [self scanWithoutBreakConnect];
        }
    }
}

- (void)scanWithBreakConnect {
    NSLog(@"完全的开始重新扫描...");
    [self resetDiscoverPeripheral];
    [self scanWithoutBreakConnect];
}

// 重置外围设备.
- (void)resetDiscoverPeripheral {
    if (_discoverPeripheral) {
        _discoverPeripheral.delegate = nil;
        [_centralManager cancelPeripheralConnection:_discoverPeripheral];
        _discoverPeripheral = nil;
    }
    _model = nil;
}

// 扫描
- (void)scanWithoutBreakConnect {
//    NSLog(@"当前用户ID >>>>%@ >>>access_token:%@", SN_USER.user_id, SN_USER.access_token);
    
    [_centralManager stopScan];
    if (SN_USER.user_id.integerValue > 0 && SN_USER.access_token.length > 0) {
    } else {
        return;
    }
    
    // 先停止扫描然后继续扫描. 避免因为多线程操作设备数组导致崩溃.
    //    if (![HASLOGIN getBOOLValue]) {
    //        return;
    //    }
    // 将之前的设备移除然后扫描添加新的设备
    [_devicesArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop)
     {
         KKBLEModel *model = obj;
         switch (model.peripheral.state) {
             case CBPeripheralStateConnected:
                 break;
             default:
             {
                 [_devicesArray removeObject:model];
             }
                 break;
         }
     }];
    
    // //serviceUUIDs用于扫描一个特点ID的外设 options用于设置一些扫描属性 键值如下
    /*
     //是否允许重复扫描 对应NSNumber的bool值，默认为NO，会自动去重
     NSString *const CBCentralManagerScanOptionAllowDuplicatesKey;
     //要扫描的设备UUID 数组 对应NSArray hovertree.com
     NSString *const CBCentralManagerScanOptionSolicitedServiceUUIDsKey;
     */
//    [self.centralManager scanForPeripheralsWithServices:KKBLEConfig.deviceServices
//                                                options:nil];
    
    //
    [self.centralManager scanForPeripheralsWithServices:nil
                                                options:nil];
    [self retrieveConnectedPeripherals];       // 老的方法去发现系统蓝牙设置已经连接过的手环
    
    [self retrieveIsConnectedPeripherals];    // 新的查询(连接)
}

// 新的查询(连接)
- (void)retrieveIsConnectedPeripherals {
    _isFoundPair = NO;
    NSArray *arrayService = [NSArray array];
    
    // //根据服务id获取所有连接的设备
    arrayService = [self.centralManager retrieveConnectedPeripheralsWithServices:@[KK_BLEServiceX9]];
    NSLog(@"已经配对连接上的手环>>>%@",arrayService);
    
    for (CBPeripheral *p  in arrayService) {
        [self discoverANCS:p];
    }
}

- (void)discoverANCS:(CBPeripheral *)peripheral {
    NSString *lastConnectMac  = [[KK_BLELastDeviceMac getObjectValue] uppercaseString];
    NSString *lastConnectUuid = [KK_BLELastDevice getObjectValue];
    
    if ([[[[peripheral.identifier UUIDString] getObjectValue]uppercaseString] isEqualToString:lastConnectMac] && [[peripheral.identifier UUIDString]isEqualToString:lastConnectUuid]) {
        _isFoundPair = YES;
        NSLog(@"已经连接上的蓝牙Name:%@ uuid>>%@ Mac:>>%@", peripheral.name, [peripheral.identifier UUIDString], [[peripheral.identifier UUIDString] getObjectValue]);
    }
    //
    [self centralManager:_centralManager
   didDiscoverPeripheral:peripheral
       advertisementData:[NSDictionary dictionary]
                    RSSI:@(0)];
}

// 老的方法去发现系统蓝牙设置已经连接过的手环
- (void)retrieveConnectedPeripherals {
    NSArray *arrayService = [NSArray array];
    arrayService = [self.centralManager retrieveConnectedPeripheralsWithServices:@[KK_BLEServiceX9]];
    NSLog(@"已经配对连接上的手环>>>%@",arrayService);
    
    NSMutableArray *array = [NSMutableArray array];
    for (CBPeripheral *Peripheral in arrayService) {
        if (![array containsObject:Peripheral]) {
            [array addObject:Peripheral];
        }
    }

    for (CBPeripheral *Hp in array) {
        NSString   *deviceUuid = Hp.identifier.UUIDString;
        NSString   *deviceName = Hp.name;
        KKBLEModel *model      = [self checkIsAddInAllWareWithID:deviceUuid];
        if (!model) {
            model = [KKBLEModel initWithUUID:deviceUuid];
        }
        model.bleName    = deviceName;
        model.peripheral = Hp;
        model.bleUUID    = [Hp.identifier UUIDString];
        NSString *mac = [model.bleUUID getObjectValue];
        if (mac) {
            model.bleMAC = [mac uppercaseString];
        }
        [self addDeviceBleWithModel:model];
        [self updateModel:nil type:KKBLEUpdateNormal];
    }
}

#pragma mark --- CBCentralManagerDelegate ---
- (void)centralManagerDidUpdateState:(CBCentralManager *)central {
    if (central.state != CBCentralManagerStatePoweredOn) {
        _centerPowerOn            = NO;
        KK_BLEService.isFoundChar = NO;
        LogWrite(@"手机蓝牙关闭", nil, nil);
        [self updateModel:_model type:KKBLEUpdatePowerOff];
        return;
    } else {
        _centerPowerOn = YES;
        [self updateModel:_model type:KKBLEUpdatePowerOn];
        LogWrite(@"手机蓝牙打开", nil, nil);
    }
    [self scanWithoutBreakConnect];
}

- (void)stopScan {
    [self.centralManager stopScan];
    LogWrite(@"停止扫描", nil, nil);
}


// 888888

//  扫描的结果会在如下代理方法中回掉：
//peripheral 扫描到的外设
//advertisementData是外设发送的广播数据
//RSSI 是信号强度 http://www.cnblogs.com/roucheng/
- (void) centralManager:(CBCentralManager *)central
    didDiscoverPeripheral:(CBPeripheral *)peripheral
        advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI {
    
    // NSLog(@"peripheral  peripheral   ====   %@",peripheral);
    int rssi = abs([RSSI intValue]);
//
    if (rssi > 100) {
        return;
    }
    
    if (_devicesArray.count > 30) {
        BOOL add = YES;
        for (int i = 0; i < _devicesArray.count; i++) {
            KKBLEModel *kkModel = _devicesArray[i];
            if (rssi < kkModel.bleRSSI.intValue) {
                add = NO;
                break;
            }
        }
        if (!add) {
            return;
        }
    }
    
    // 获取设备的名字，设备拥有广播名和设备名，2个名字通常情况下一致，但有时不一致.
    NSString *deviceName = peripheral.name;
    NSString *idString   = [peripheral.identifier UUIDString];
    
    if (!_isUpdateing) {
       
    }
    if (!deviceName) {
        return;
    }
    
//     NSLog(@"扫描到蓝牙外设:..%@..%@..%@..~~~~~ %d", advertisementData, [peripheral.identifier UUIDString], peripheral.name, rssi);
    
    // 打开99999
       NSInteger advInt;
       NSString *advS;
//       NSData *kCData2 = [advertisementData objectForKey:@"kCBAdvDataManufacturerData"];
//       if (kCData2) {
//           UInt8  val[2048] = {0};
//           [kCData2 getBytes:&val length:kCData2.length];
//           advInt = val[0]*256+val[1];
//           advS = [NSString stringWithFormat:@"%d",advInt];
//       }
//       else
//       {
//           advInt = 0;
//           advS = [NSString stringWithFormat:@"%d",advInt];
//       }
//       NSLog(@"🙂🙂🙂advS22222 >>>>%@",advS);
//       BOOL adv = [KKBLEConfig isFitAdv:advS];
//        otaName =[peripheral.name lowercaseString];
//        if ([otaArray containsObject:otaName]||advInt == 0) {
//            adv = YES;
//        }
//        if(!adv)
//        {
//            return;
//        }
    
//     NSLog(@"扫描到蓝牙外设:..%@..%@..%@..~~~~~ %d", advertisementData, [peripheral.identifier UUIDString], peripheral.name, rssi);
    
    // 先在设备列表数组里面查找有没有.
    if (!_isUpdateing) {
//        KKBLEModel *model = [KKBLEModel getModelFromDBWtihUUID:idString];
        KKBLEModel *model = [KKBLEModel initWithUUID:idString];
        //            model = [KKBLEModel getModelFromDBWtihUUID:deviceUuid];
        
        model.bleName    = deviceName;
        model.bleRSSI    = [NSString stringWithFormat:@"%d", ABS(RSSI.intValue)];
        model.peripheral = peripheral;
        model.bleUUID    = [peripheral.identifier UUIDString];
        // 每次都初始化确保正确性.
        model.isInitiative = NO;
        NSString *mac;
               NSData *kCData2 = [advertisementData objectForKey:@"kCBAdvDataManufacturerData"];
               if (kCData2) {
                       const unsigned *kCData = [kCData2 bytes];
                   mac = [NSString stringWithFormat:@"%08x%08x%08x%08x",
                   ntohl(kCData[0]), ntohl(kCData[1]),ntohl(kCData[2]),ntohl(kCData[3])];
               }

        if (mac.length >= 19) {
            NSString *macAddress    = [mac substringWithRange:NSMakeRange(4, 12)];
            NSString *s1            = [macAddress substringWithRange:NSMakeRange(0, 2)];
            NSString *s2            = [macAddress substringWithRange:NSMakeRange(2, 2)];
            NSString *s3            = [macAddress substringWithRange:NSMakeRange(4, 2)];
            NSString *s4            = [macAddress substringWithRange:NSMakeRange(6, 2)];
            NSString *s5            = [macAddress substringWithRange:NSMakeRange(8, 2)];
            NSString *s6            = [macAddress substringWithRange:NSMakeRange(10, 2)];
            NSString *bltMacAddress = [NSString stringWithFormat:@"%@:%@:%@:%@:%@:%@", s1, s2, s3, s4, s5, s6];
            model.bleMAC = [bltMacAddress uppercaseString];
            NSString *bleAdv = [mac substringWithRange:NSMakeRange(0, 4)];
            model.bleAdv = [bleAdv dataUsingEncoding:NSUTF8StringEncoding];
            model.bleAdvID = advInt;
        }
        else
        {
            model.bleAdvID = 0;
        }
        [self addDeviceBleWithModel:model];
                   NSArray *resultArray = [_devicesArray sortedArrayUsingComparator:^NSComparisonResult (id obj1, id obj2) {
                       KKBLEModel *per1 = obj1;
                       KKBLEModel *per2 = obj2;
                       if (per1.bleRSSI.intValue > per2.bleRSSI.intValue) {
                           return NSOrderedDescending;//降序
                       } else if (per1.bleRSSI.intValue < per2.bleRSSI.intValue) {
                           return NSOrderedAscending;//升序
                       } else {
                           return NSOrderedSame;//相等
                       }
                   }];
                   [_devicesArray removeAllObjects];
         
                   for (int i = 0; i < resultArray.count; i++) {
                       if (i < 30) {
                            
                           KKBLEModel *addModel = resultArray[i];
                           [_devicesArray addObject:addModel];
                       }
                   }
        [self newToConectBle:model];
    }
    
    // 新增OTAOTA
  if ([otaArray containsObject:otaName]) {
      NSString *mac;
      NSData *kCData2 = [advertisementData objectForKey:@"kCBAdvDataManufacturerData"];
      if (kCData2) {
              const unsigned *kCData = [kCData2 bytes];
          mac = [NSString stringWithFormat:@"%08x%08x%08x%08x",
          ntohl(kCData[0]), ntohl(kCData[1]),ntohl(kCData[2]),ntohl(kCData[3])];
      }
      NSString *macAddress    = [mac substringWithRange:NSMakeRange(4, 12)];
      NSString *s1            = [macAddress substringWithRange:NSMakeRange(0, 2)];
      NSString *s2            = [macAddress substringWithRange:NSMakeRange(2, 2)];
      NSString *s3            = [macAddress substringWithRange:NSMakeRange(4, 2)];
      NSString *s4            = [macAddress substringWithRange:NSMakeRange(6, 2)];
      NSString *s5            = [macAddress substringWithRange:NSMakeRange(8, 2)];
      NSString *s6            = [macAddress substringWithRange:NSMakeRange(10, 2)];
      NSString *bltMacAddress = [NSString stringWithFormat:@"%@:%@:%@:%@:%@:%@", s1, s2, s3, s4, s5, s6];
      
      bltMacAddress = [bltMacAddress uppercaseString];
      bool found = NO;
      if (s1.intValue || s2.intValue || s3.intValue || s4.intValue ||s5.intValue ||s6.intValue) {
          found = YES;
      }
      if (ABS(RSSI.intValue) > 90) {
          return;
      }
      if (found) {
          if (_getOtaDic) {
              NSLog(@"🙂🙂🙂不要频发请求OTA接口>>>>");
              return;
          }
          NSLog(@"🙂获取升级文件开始");
          _getOtaDic = YES;
          
          LogWrite(nil, ([NSString stringWithFormat:@"rssi:%d", ABS(RSSI.intValue)]), nil);
          NSString *find = [NSString stringWithFormat:@"🙂🙂🙂找到有可以升级的设备%@ %@ found:%i",otaName,bltMacAddress,found];
            LogWrite(nil, find, nil);
        NSLog(@"🙂🙂🙂找到有可以升级的设备>>>>>>>>>>>>>>%@ %@ found:%i",otaName,bltMacAddress,found);
          [self performSelector:@selector(delayBackgetOtaDic) withObject:nil afterDelay:6.0];
          [SN_Net updateWithOtaMac:bltMacAddress with:^(id object) {
              NSDictionary *dic = object[@"data"];
              NSInteger code = [object[@"ret"]integerValue];
              if (code == 0) {
//                  NSLog(@"🙂OTA>>>>%@",dic);
                  NSInteger advId =  [dic[@"adv_id"]integerValue];
                  if (advId > 0) {
                      KK_BLEModel.bleAdvID = [dic[@"adv_id"]integerValue];
                      KK_BLEModel.bleCustomerID = [dic[@"customid"]integerValue];
                      KK_BLEModel.deviceID = [dic[@"upgradeid"]integerValue];
                      NSDictionary *dict = @{@"adv_id" : @(KK_BLEModel.bleAdvID), @"customid" : @(KK_BLEModel.bleCustomerID), @"upgradeid":@(KK_BLEModel.deviceID)};
                      NSLog(@"🙂🙂🙂 新的升级模式 匹配到服务器升级设备>>>%@",dict);
                      LogWrite(nil, @"新的升级模式 匹配到服务器升级设备>>", nil);
                      [self oldOtaUpdate];
                  }
              }
              else
              {
                  NSLog(@"🙂老的升级 没有匹配到服务器升级设备>>>");
                   LogWrite(nil, @"老的升级 没有匹配到服务器升级设备>>>>", nil);
                  [self oldOtaUpdate];
              }
          } fail:^(id object) {
             
          }];
      }
      else
      {
          NSLog(@"🙂老的升级 没有匹配到服务器升级设备>>>");
          LogWrite(nil, @"老的升级 没有匹配到服务器升级设备>>>>", nil);
          [self oldOtaUpdate];
      }
      // 0 旧  1 新
    }
    
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, 3.0 * NSEC_PER_SEC);
    dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
        [self updateModel:nil type:KKBLEUpdateNormal];
    });
}
// 888888
- (void)delayBackgetOtaDic
{
    NSLog(@"🙂获取升级文件复位");
    self.getOtaDic = NO;
}
// 888888
- (void)oldOtaUpdate
{
    if (!KK_ShareData.isDown) {
        [[FileModelEntity sharedInstance] checkUpdateFirmwareInfo];
    }
    else
    {
        dispatch_async(dispatch_get_main_queue(), ^{
            [self updateOtaShow];
        });
    }
    [FileModelEntity sharedInstance].block = ^{
        NSLog(@"🙂下载升级OTA文件回调成功>>>>%i",KK_ShareData.isDown);
        dispatch_async(dispatch_get_main_queue(), ^{
            if ([otaArray containsObject:otaName]) {
            [self updateOtaShow];
            }
        });
    };
}

// 888888
- (void)updateOtaShow
{
            if (KK_ShareData.isDown) {
    //            NSLog(@"下载升级包成功 开始连接升级>>>>>>>>>>>>");
    //            LogWrite(@"下载升级包成功 开始连接升级", nil, nil);
                if (!_isUpdateing) {
                    if (KK_ShareData.updateViewShow) {
                        return;
                    }
                    if (_updateInfoView) {
                        [_updateInfoView removeFromSuperview];
                        _updateInfoView = nil;
                    }
                    NSLog(@"🙂OTA升级弹窗>>>>");
                    _updateInfoView       = [[UpdateInfoView alloc] init];
                    _updateInfoView.frame = CGRectMake(0, 0, kSCREEN_WIDTH, 150);
                    [_updateInfoView popupWithtype:PopupViewOption_colorLump succeedBlock:^(UIView *View)
                     {
                         View.center = CGPointMake(kSCREEN_WIDTH/2, kSCREEN_HEIGHT/2);
                     }                dismissBlock:^(UIView *View)
                     {
                        self.getOtaDic = NO;
                     }];
                }  //pu'tao
            }
}

// 888888
- (void)newToConectBle:(KKBLEModel *)model
{
    NSString *blename = [model.bleName lowercaseString];
    if ([otaArray containsObject:blename]) {
        NSLog(@"🙂不自动连接空中升级>>>>");
        return;
    }
    
//        NSLog(@"要连接的设备>>>%@",model);
        // 扫描到设备后是否自动连接 //需要绑定设备
        NSString *uuidL = [KK_BLELastDevice getObjectValue];
        NSString *macL  = [KK_BLELastDeviceMac getObjectValue];
        if (macL.length > 10) {
            if (([macL isEqualToString:model.bleMAC])) {
                [self connectPeripheralWithModel:model];
                return;
            }
        }
        if (uuidL.length > 10) {
            if (([uuidL isEqualToString:model.bleUUID])) {
                [self connectPeripheralWithModel:model];
                return;
            }
        }
}

// 连接指定的设备
- (void)connectPeripheralWithModel:(KKBLEModel *)model {
    if (!model.peripheral) {
        return;
    }
    if (!model.isConnected) {
        if (_model.isConnected) {
            // 将当前连接的模型干掉...
            [self initiativeDismiss];
        }
        _model = model;
        // 进行配置, 分析蓝牙协议, 服务特征.
        _config = [KKBLEConfig configWithModel:_model];
        dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, 1.0 * NSEC_PER_SEC);
        dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
            // 连接模型
            if (_model.peripheral != nil) {
                [_centralManager connectPeripheral:_model.peripheral options:nil];
                [self updateModel:_model type:KKBLEUpdateConnecting];
                LogWrite(@"连接指定的设备", ([NSString stringWithFormat:@"%@", model.bleMAC]), nil);
                // 停止扫描 省电 也可以不停止
                [_centralManager stopScan];
            }
        });
    }
}

// 检查设备数组里面是否已经存在持有idstring的设备
- (KKBLEModel *)checkIsAddInAllWareWithID:(NSString *)idString {
    LogWrite(@"手机底层连接设备", ([NSString stringWithFormat:@"%@", _devicesArray]), nil);
    for (KKBLEModel *model in _devicesArray) {
        if ([model.bleUUID isEqualToString:idString]) {
            return model;
        }
    }
    return nil;
}

// 手机连接到蓝牙设备但是并未发现该设备的服务与特征。可以说是还未真正的连接。
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral {
    NSLog(@"连接到设备, 并去发现服务.");
    _discoverPeripheral          = peripheral;
    _discoverPeripheral.delegate = KK_BLEService;
    KK_BLEService.peripheral     = _discoverPeripheral;
    NSLog(@"did connect peripheral name>>>>%@", peripheral.name);
    if ([[peripheral.name lowercaseString] isEqualToString:[@"XW_OTA" lowercaseString]] || [[peripheral.name lowercaseString] isEqualToString:[@"DfuTarg" lowercaseString] ]|| [[peripheral.name lowercaseString]isEqualToString:[@"B2_OTA" lowercaseString]] ||[[peripheral.name lowercaseString]isEqualToString:[@"PPlusOTA" lowercaseString]]) {
        _isUpdateing = YES;
    } else {
        _isUpdateing = NO;
    }
    if (!_isUpdateing) {
        [_discoverPeripheral discoverServices:@[_config.service, [CBUUID UUIDWithString:@"0xFF00"],[CBUUID UUIDWithString:SERVICE_OTA_UUID]]];
    } else {
        [_discoverPeripheral discoverServices:@[_config.updateService]];
    }
    [self stopScan];
    _isConnected = YES;
}

// 连接失败 这个回调很少触发
- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error {
    [self scanWithBreakConnect];
    [self updateModel:_model type:KKBLEUpdateDisConnect];
}

// 设备断开连接时触发，但是因为强行关闭蓝牙设备不会回调， 断开蓝牙的回调参见:centralManagerDidUpdateState
- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error {
    NSLog(@"蓝牙断开连接>>>>>>>>>>>>>>>>>");
    KK_BLEService.isFoundChar = NO;
    //    _isFoundPair = NO;
    if (!_isUpdateing) {
    } else {
        [self scanWithBreakConnect];
    }
    KKBLEModel *model = [self findModelWithPeripheral:peripheral];
    if (model) {
        if (model.isInitiative) {
            model.isInitiative = NO;
            [LogManager sharedInstance].breakTimes++;
            LogWrite(@"蓝牙自己断开", ([NSString stringWithFormat:@"次数:%ld,RSSi:%@", (long)[LogManager sharedInstance].breakTimes, model.bleRSSI]), nil)
            [self scanWithBreakConnect];
        } else {
            if (!_isUpdateing) {
                [self waitFewSecondsBeforeRepeatScan];
            }
        }
    } else {
        [self scanWithBreakConnect];
    }
    [self updateModel:_model type:KKBLEUpdateDisConnect];
    _isConnected = NO;
}

// 10秒内没连接上就重新扫描
- (void)waitFewSecondsBeforeRepeatScan {
    [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(scanIfDisConnect) object:nil];
    [self performSelector:@selector(scanIfDisConnect) withObject:nil afterDelay:10.0];
}

// 重新扫描，条件是手机没有连接蓝牙设备，有连接就无需扫描
- (void)scanIfDisConnect {
    if (!self.isConnected) {
        [self scanWithBreakConnect];
    }
}

// 从连接的设备组里面移除掉某个设备.
- (void)removeModelWithPeripheral:(CBPeripheral *)peripheral withArray:(NSMutableArray *)array {
    [array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop)
     {
         KKBLEModel *model = obj;
         if (model.peripheral == peripheral) {
             [array removeObject:model];
             *stop = YES;
         }
     }];
}

// 在所有准备连接的数组中 根据设备寻找模型.
- (KKBLEModel *)findModelWithPeripheral:(CBPeripheral *)peripheral {
    for (KKBLEModel *model in _devicesArray) {
        if ([model.bleUUID isEqualToString:[peripheral.identifier UUIDString]]) {
            return model;
        }
    }
    return nil;
}

// 主动断开设备并且不需要重新连接.
- (void)initiativeDismiss {
    NSLog(@"主动断开设备并不重连.");
    if (self.isConnected) {
        _model.isInitiative = YES;
        [_centralManager cancelPeripheralConnection:_model.peripheral];
    }
}

- (void)disConnect {
    if (self.isConnected) {
        [_centralManager cancelPeripheralConnection:_model.peripheral];
    }
    [self resetDiscoverPeripheral];
}

// 解绑设备
- (void)exPairDevice {
    [LASTCONNECTBLEHEAD setIntValue:0];
    [KK_BLELastDevice setObjectValue:@""];
    [KK_BLELastDeviceMac setObjectValue:@""];
    KK_BLEModel.bleAdvID = 0;
    KK_BLEModel.function = 0;
    [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"isHadRequestBleFunction"];
    [[NSUserDefaults standardUserDefaults] synchronize];
    [SN_USER updateToDB];
    [[NSUserDefaults standardUserDefaults] removeObjectForKey:@"orderTagArray"];
    [KK_BLEModel updateToDB];
    [self initiativeDismiss];
    [self scanWithBreakConnect];
}

// 开始对设备进行空中升级.
- (void)startUpdateFirmWare {
    [KK_BLESend resetSendCMD];
    _isUpdateing = YES;
    _updateModel = _model;
    if (_updateModel.bleUUID) {
        [GF_LastUpdateUUID setObjectValue:_updateModel.bleUUID];
    }
    [KK_BLESend sendUpdateFirmwareWithUpdateBlock:^(id object, KKBLEAcceptType type)
     {
     }];
}

// 升级结束 可能失败 可能成功.
- (void)firmWareUpdateEnd:(BOOL)success {
    _isUpdateing = NO;
    _updateModel = nil;
    _model       = nil;
}

// 添加设备
- (void)addDeviceBleWithModel:(KKBLEModel *)model {
    if (!model) {
        return;
    }
    if (!model.peripheral) {
        return;
    }
    BOOL found = NO;
    for (KKBLEModel *mmModel in _devicesArray) {
        if ([mmModel.bleUUID isEqualToString:model.bleUUID]) {
            found = YES;
            break;
        }
    }
    if (!found) {
        [_devicesArray addObject:model];
    }
}

@end
